package com.mapfinal.server.auth;

import java.sql.Timestamp;

import com.jfinal.aop.Clear;
import com.jfinal.kit.Ret;
import com.jfinal.kit.StrKit;
import com.lambkit.Lambkit;
import com.lambkit.common.util.EncryptUtils;
import com.lambkit.common.util.RequestUtils;
import com.lambkit.web.WebConfig;
import com.mapfinal.server.auth.model.User;
import com.mapfinal.server.web.MapfinalServerController;

public class AuthController extends MapfinalServerController {

	public void index() {
		keepPara();
		renderTemplate("index.html");
	}
	
	@Clear
	public void randomCode() {
		renderCaptcha();
	}
	
	@Clear(value={AuthInterceptor.class})
	public void login() {
		if(getRequest().getMethod()=="POST")  {
			doLogin();			
		} else if(getRequest().getMethod()=="GET")  {
			renderTemplate("login.html");	
		} else {
			renderNull();
		}
	}
	
	private void doLogin() {
		String username = getPara("username");
		String password = getPara("password");
		String captcha = getPara("captcha");
		if(AuthKit.getLoginError(getSession()) > AuthKit.AccountLockerNum) {
			setLog("10107", "设备已锁定", username);
			renderJson(Ret.fail("msg", "设备已锁定！").set("code", 10107));
			return;
		}
        if(AuthKit.getLoginError(username) > AuthKit.AccountLockerNum) {
        	setLog("10108", "帐号已锁定", username);
        	renderJson(Ret.fail("msg", "帐号已锁定！").set("code", 10108));
			return;
        }
		if(StrKit.isBlank(username)) {
			setLog("10101", "帐号不能为空", username);
			renderJson(Ret.fail("msg", "帐号不能为空！").set("code", 10101));
			return;
		}
		if(StrKit.isBlank(password)) {
			setLog("10102", "密码不能为空", username);
			renderJson(Ret.fail("msg", "密码不能为空！").set("code", 10102));
			return;
		}
		if(StrKit.isBlank(captcha)) {
			setLog("10103", "验证码不能为空", username);
			renderJson(Ret.fail("msg", "验证码不能为空！").set("code", 10103));
			return;
		}
		if (!validateCaptcha("captcha")) {
			setLog("10104", "验证码不正确", username);
			renderJson(Ret.fail("msg", "验证码不正确！").set("code", 10104));
			return;
		}
		//Users.service().getUser(username, Users.service().getPasswordSecurity(password));
		User user = User.service().findByLoginName(username);
		if(user==null) {
			Integer error = AuthKit.addLoginError(getSession());
			setLog("10105", "帐号不存在", username);
			renderJson(Ret.fail("msg", "帐号不存在！错误" + error + "次，错误3次后锁定").set("code", 10105));
			return;
		}
		if(AuthKit.getLoginError(user.getUserName()) > AuthKit.AccountLockerNum) {
			setLog("10108", "帐号已锁定", username);
        	renderJson(Ret.fail("msg", "帐号已锁定！").set("code", 10108));
			return;
        }
		if(user.isLocked()) {
			setLog("10109", "账号已被禁用", username);
			renderJson(Ret.fail("msg", "账号已被禁用！").set("code", 10109));
			return;
		}
		String salt = user.getSalt();
		String pswd = EncryptUtils.md5WithPrefix(password, salt);
		if (user.getPassword().equals(pswd)) {
			//将当前用户保存在Session中。
			setSessionAttr("user", user.getName());
			Timestamp time = new Timestamp(System.currentTimeMillis());
			user.set("last_login_ip", RequestUtils.getIpAddress(getRequest())).set("last_login_time", time);
			user.update();
			AuthLoginCache.login(user);
		} else {
			setLog("10106", "密码错误", username);
			Integer error = AuthKit.addLoginError(user.getUserName());
			renderJson(Ret.fail("msg", "密码错误！错误" + error + "次，错误3次后锁定").set("code", 10106));
			return;
		}
		WebConfig web = Lambkit.config(WebConfig.class);
		setLog("10100", "登录成功", username);
		renderJson(Ret.ok("data", web).set("type", user.getType()).set("roles", user.getRoles()).set("url", getPara("homeurl")));
	}
	
	private void setLog(String result, String description, String params) {
		setAttr("Log_Result", result);
		setAttr("Log_Description", description);
		setAttr("Log_Parameter", params);
	}

	public void logout() {
		getSession().invalidate();
		String userName = getSessionAttr("user");
		AuthLoginCache.logout(userName);
		removeSessionAttr("user");
		if(getRequest().getMethod()=="POST")  {
			WebConfig web = Lambkit.config(WebConfig.class);
			renderJson(Ret.ok("data", web));
		} else {
			login();
		}
	}
	
	private boolean rexCheckPassword(String input) {
        // 8-20 位，字母、数字、字符
        String regStr = "^(?![a-zA-Z]+$)(?![A-Z0-9]+$)(?![A-Z\\W_]+$)(?![a-z0-9]+$)(?![a-z\\W_]+$)(?![0-9\\W_]+$)[a-zA-Z0-9\\W_]{8,20}$";
        return input.matches(regStr);
    }
	
	public void pswd() {
		if(isPOST()) {
			String userName = getSessionAttr("user");
			if(StrKit.isBlank(userName)) {
				renderJson(Ret.fail("msg", "用户未登录或登录已过期！"));
				return;
			}
			String password = getPara("password");
			String newpassword = getPara("newpassword");
			String repassword = getPara("repassword");
			if(StrKit.isBlank(password) || StrKit.isBlank(newpassword) || StrKit.isBlank(repassword)) {
				renderJson(Ret.fail("msg", "密码不能为空！"));
				return;
			}
			if(!newpassword.equals(repassword)) {
				renderJson(Ret.fail("msg", "输入的新密码不一致！"));
				return;
			}
			if(!rexCheckPassword(newpassword)) {
				renderJson(Ret.fail("msg", "新密码必须在8-20位，包含大小写字母,数字,特殊字符中的至少3种！"));
				return;
			}
			String captcha = getPara("captcha");
			if(StrKit.isBlank(captcha)) {
				renderJson(Ret.fail("msg", "验证码不能为空！"));
				return;
			}
			if (!validateCaptcha("captcha")) {
				renderJson(Ret.fail("msg", "验证码不正确！"));
				return;
			}
			User user = User.service().findByUserName(userName);
			if (user != null) {
				String salt = user.getSalt();
				String pswd0 = EncryptUtils.md5WithPrefix(password, salt);
				String pswd1 = EncryptUtils.md5WithPrefix(newpassword, salt);
				if(pswd1.equals(pswd0)) {
					renderJson(Ret.fail("msg", "新密码不能与旧密码相同！"));
					return;
				}
				if(!user.getPassword().equals(pswd0)) {
					renderJson(Ret.fail("msg", "旧密码错误！"));
					return;
				}
				if(user.isLocked()) {
					renderJson(Ret.fail("msg", "账号已被锁定！"));
					return;
				}
				user.setUserPass(pswd1);
				boolean flag = user.update();
				if(!flag) {
					renderJson(Ret.fail("msg", "修改密码失败！"));
					return;
				}
			} else {
				renderJson(Ret.fail("msg", "用户已退出！"));
				return;
			}
			renderJson(Ret.ok("url", getPara("homeurl")));
		} else {
			keepPara();
			renderTemplate("pswd.html");
		}
	}
	
	public void needPermission() {
		render("/lambkit/errors/needPermission.html");
	}
}
